/***********************************************************************
This file is part of the ChipWhisperer Project. See www.newae.com for more
details, or the codebase at http://www.chipwhisperer.com

Copyright (c) 2022, NewAE Technology Inc. All rights reserved.
Author: Jean-Pierre Thibault <jpthibault@newae.com>

  chipwhisperer is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  chipwhisperer is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with chipwhisperer.  If not, see <http://www.gnu.org/licenses/>.
*************************************************************************/

//////////////////////////////////////////////////////////////////////////////////
// General Top-Level Module for iCEUP5K Target. 
// Adapted from CW308T_S6LX9_SS.v.
//
//////////////////////////////////////////////////////////////////////////////////


`timescale 1 ns / 1ps
`default_nettype none

module ss_ice40_aes_top (
    input  wire clk,
    output wire TxD,
    input  wire RxD,
    output wire IO4,
    output wire IO3,            // used as a "clock alive" indicator
    output wire clock_alive     // just for common .pcf file
);

    wire enc_busy;
    wire clk_alive_en = ~enc_busy;
    assign IO3 = clk_alive_en? count[23] : 1'b0;
    assign clock_alive = 1'b0;

    reg [23:0] count;
    always @(posedge clk) count <= count + 1;

    wire [127:0] enc_input;     // Input to encryption algorithm (normally PT)
    wire [127:0] enc_output;    // Output from encryption algorithm (normally CT)
    wire [127:0] enc_key;       // Encryption key to use
    wire load_input;            // One-clock cycle flag to indicate data in enc_input is valid
    wire load_key;              // One-cycle flag to indicate data in enc_input is valid
    wire enc_go;                // One-cycle flag to indicate we should run an encryption
    wire enc_output_ready;      // One-cycle flag generated by encryption core indicating data out is valid

    SimpleSerial SSCore(
        .clk            (clk), 
        .TxD            (TxD), 
        .RxD            (RxD), 
        .LED_rx         (), 
        .LED_go         (),
        .pt             (enc_input), 
        .key            (enc_key), 
        .load_key       (load_key), 
        .load_pt        (load_input),
        .do_enc         (enc_go), 
        .ct             (enc_output), 
        .ct_ready       (enc_output_ready)
    );

    assign IO4 = enc_busy;

    aes_core AESGoogleVault(
        .clk        (clk),
        .load_i     (enc_go),
        .key_i      ({enc_key, 128'h0}),
        .data_i     (enc_input),
        .size_i     (2'd0),
        .dec_i      (1'b0),
        .data_o     (enc_output),
        .busy_o     (enc_busy)
    );

    //Generate single-clock cycle pulse when enc_busy falls
    reg enc_done_flag;
    reg enc_busy_delayed;

    always @(posedge clk) begin
        enc_busy_delayed <= enc_busy;
        enc_done_flag <= ~enc_busy & enc_busy_delayed;
    end

    assign enc_output_ready = enc_done_flag;

endmodule

`default_nettype wire

